#include "isi.h"
#include <QtSql>
#include "QSqlDatabase"
#include "QString"
#include <QSqlError>


Isi::Isi(const int numConnection, QObject *parent) : QObject(parent)
{
    d_nameConnection = "db" + QString::number(numConnection);
    d_db = QSqlDatabase();
    d_db = QSqlDatabase::addDatabase("QSQLITE",d_nameConnection);
}

Isi::~Isi()
{
    QString connectionName = d_db.connectionName();
    if(d_db.isOpen()){
        d_db.close();
    }
    d_db = QSqlDatabase();
    QSqlDatabase::removeDatabase(connectionName);
}

void Isi::createTable()
{
    d_db.open();
    QSqlQuery query(d_db);
    query.exec("CREATE TABLE header(time_gmt INTEGER, time_sev INTEGER, channels_in INTEGER, channels_out INTEGER)");
    query.exec("CREATE TABLE data(id BIGINT NOT NULL PRIMARY KEY ASC, time_gmt INTEGER KEY, time_sev INTEGER KEY, value_in INTEGER, value_out INTEGER);");
    d_db.close();
}

bool Isi::insertHeader(QStringList list)
{
    d_db.open();
    bool ok;
    QSqlQuery query(d_db);
    ok = query.exec(QString("INSERT INTO header(time_gmt, time_sev, channels_in, channels_out) VALUES (%1, %2, %3, %4);").arg(list.at(0)).arg(list.at(1)).arg(list.at(2)).arg(list.at(3)));
    d_db.close();
    return ok;
}

bool Isi::insertData(QStringList list)
{
    d_db.open();
    bool ok;
    QSqlQuery query(d_db);
    query.prepare("INSERT INTO data (id, time_gmt, time_sev, value_in, value_out) VALUES (?,?,?,?,?);");
    query.addBindValue(list.at(0));
    query.addBindValue(list.at(1));
    query.addBindValue(list.at(2));
    query.addBindValue(list.at(3));
    query.addBindValue(list.at(4));
    ok = query.exec();
    d_db.close();
    return ok;

}

int Isi::selectRow(int elapsed)
{
    d_db.open();
    QSqlQuery query(d_db);
    qDebug()<< "elapsed " << elapsed;
    QString query1 = QString("SELECT rowid as d_row from data where time_sev > %1 limit 1;").arg(elapsed*1000000L);
    query.exec(query1);
    if(query.first()){


        int value = query.value("d_row").toInt();
        d_db.close();
        qDebug() << " row = "<<value;
        return value;
    }
    else
    {
        qDebug() << "зашел в условие в selectRow";
        return 0;
    }
}

double Isi::selectTime(int row, int column)
{
    d_db.open();
    QSqlQuery query(d_db);
    QString queryTime ="";
    //    queryTime = QString("SELECT(h.time_gmt + d.time_gmt),(h.time_sev + d.time_sev)from header as h, data as d where d.rowid=%1;").arg(row);  ///запрос для абсолютного времени
    queryTime = QString("SELECT time_gmt, time_sev from data  where rowid=%1;").arg(row);
    query.exec(queryTime);
    query.first();
    double value = query.value(column).toLongLong()/1000000.0L;
    //    double value = query.value(column).toLongLong();
    d_db.close();
    return value;

}

qint64 Isi::selectValue(int row, int column, int bit)
{
    d_db.open();
    QSqlQuery query(d_db);
    qint64 res=0;
    if(column == 3)
    {
        QString queryValueIn;
        queryValueIn = QString ("SELECT value_in from data where rowid = %1;").arg(row);
        query.exec(queryValueIn);
        query.first();
        int value = query.value("value_in").toInt();
        //        res = value & bit;
        if((value & bit) > 0) res=1;
        else res=0;
        qDebug() << "bit = " << res;
        d_db.close();
        return res;
    }
    if(column == 4)
    {
        QString queryValueOut = QString ("SELECT value_out from data where rowid = %1;").arg(row);
        query.exec(queryValueOut);
        query.first();
        int value = query.value("value_out").toInt();
        //        res = value & bit;

        if((value & bit) > 0) res=1;
        else res=0;
        qDebug() << "bit = " << res;
        d_db.close();
        return res;
    }
    else
    {
        d_db.close();
        return res;
    }
}

qint64 Isi::selectValue(int row, int index)
{
    int bit = 0;
    if(index > getCountIn())    //выходные каналы
    {
        //        bit = (getCountOut()+getCountIn())-index;
        bit = index - getCountIn();
        selectValue(row,ColData::valueOut,bit);
    }
    else                       //входные каналы
    {
        bit = index;
        selectValue(row,ColData::valueIn,bit);
    }
}

int Isi::getParams()
{
    return getCountIn() + getCountOut();
}

bool Isi::open()
{
    return d_db.open();
}

int Isi::getCountIn()
{
    d_db.open();
    if(!d_db.open())
    {
        qDebug()<<"d_db not open" <<d_db.lastError();
    }
    QSqlQuery query(d_db);
    QString queryIn = QString("SELECT channels_in from header;");
    query.exec(queryIn);
    query.first();
    int channels_in = query.value("channels_in").toInt();
    d_db.close();
    return channels_in;
}

int Isi::getCountOut()
{
    d_db.open();
    QSqlQuery query(d_db);
    QString queryOut = QString("SELECT channels_out from header;");
    query.exec(queryOut);
    query.first();
    int channels_out = query.value("channels_out").toInt();
    d_db.close();
    return channels_out;
}

void Isi::setPath(const QString &path)
{
    if(path=="")
    {
        QString defaultpath = (path.isEmpty())? "./../receiver":path;
        d_path = QFileDialog::getOpenFileName(0,"Выбрать файл",defaultpath, "isi (*.isi);; All file (*.*); ");
    }
    else {
        d_path = path;
    }

    if(!d_path.isEmpty())
    {
        d_db.setDatabaseName(d_path);
    }
}

QString Isi::path()
{
    return d_path;
}

QString Isi::getNameParam(int index)
{
    if(index >getCountIn())
    {
        return QString("out_%1").arg(index-getCountIn());
    }
    else
        return QString("in_%1").arg(index);
}

int Isi::getRowCount()
{
    d_db.open();
    if(!d_db.open())
    {
        qDebug()<<"d_db not open" <<d_db.lastError();
    }
    QSqlQuery query(d_db);
    QString queryRowCount = QString("SELECT max(rowid) from data;");
    query.exec(queryRowCount);
    query.first();
    int count = query.value("max(rowid)").toInt();
    d_db.close();
    return count;
}

int Isi::getColumnCount()
{
    return 5;
}

QVariant Isi::getValueItem(int row, int column)
{
    d_db.open();
    if(!d_db.open())
    {
        qDebug()<<"d_db not open" <<d_db.lastError();
    }
    QSqlQuery query(d_db);
    QString queryValue;
    switch (column)
    {
    case 0: queryValue = QString("Select id as value from data where rowid = %1").arg(row);
        break;
    case 1: queryValue = QString("Select time_gmt as value from data where rowid = %1").arg(row);
        break;
    case 2: queryValue = QString("Select time_sev as value from data where rowid = %1").arg(row);
        break;
    case 3: queryValue = QString("Select value_in as value from data where rowid = %1").arg(row);
        break;
    case 4: queryValue = QString("Select value_out as value from data where rowid = %1").arg(row);
        break;
    }
    query.exec(queryValue);
    query.first();
    long long value = query.value("value").toLongLong();
    d_db.close();
    return value;
}

int Isi::getHeaderColumnCount()
{
    return 4;
}

int Isi::getHeaderRowCount()
{
    d_db.open();
    if(!d_db.open())
    {
        qDebug()<<"d_db not open" <<d_db.lastError();
    }
    QSqlQuery query(d_db);
    QString queryRowCount = QString("SELECT max(rowid) from header;");
    query.exec(queryRowCount);
    query.first();
    int count = query.value("max(rowid)").toInt();
    d_db.close();
    return count;
}

QVariant Isi::getHeaderValueItem(int row, int column)
{
    d_db.open();
    if(!d_db.open())
    {
        qDebug()<<"d_db not open" <<d_db.lastError();
    }
    QSqlQuery query(d_db);
    QString queryValue;
    switch (column)
    {
    case 0: queryValue = QString("Select time_gmt as value from header where rowid = %1").arg(row);
        break;
    case 1: queryValue = QString("Select time_sev as value from header where rowid = %1").arg(row);
        break;
    case 2: queryValue = QString("Select channels_in as value from header where rowid = %1").arg(row);
        break;
    case 3: queryValue = QString("Select channels_out as value from header where rowid = %1").arg(row);
        break;
    }
    query.exec(queryValue);
    query.first();
    QVariant value = query.value("value");
    d_db.close();
    return value;
}
